// Neo4jValueConverter.cpp
#include "Neo4jValueConverter.h"
#include <neo4j-client.h>
#include <vector>

neo4j_value_t Neo4jValueConverter::toNeo4jValue(const graph::Neo4jValue& value) {
    neo4j_value_t neo4j_val;
    
    switch (value.value_case()) {
        case graph::Neo4jValue::kStringValue:
            neo4j_val = neo4j_string(value.string_value().c_str());
            break;
        case graph::Neo4jValue::kIntValue:
            neo4j_val = neo4j_int(value.int_value());
            break;
        case graph::Neo4jValue::kFloatValue:
            neo4j_val = neo4j_float(value.float_value());
            break;
        case graph::Neo4jValue::kBoolValue:
            neo4j_val = neo4j_bool(value.bool_value());
            break;
        case graph::Neo4jValue::kNullValue:
            neo4j_val = neo4j_null;
            break;
        case graph::Neo4jValue::kListValue:
            neo4j_val = toNeo4jValue(value.list_value());
            break;
        case graph::Neo4jValue::kMapValue:
            neo4j_val = toNeo4jValue(value.map_value());
            break;
        default:
            neo4j_val = neo4j_null;
            break;
    }
    
    return neo4j_val;
}

neo4j_value_t Neo4jValueConverter::toNeo4jValue(const graph::Neo4jList& list) {
    std::vector<neo4j_value_t> values;
    
    for (const auto& item : list.values()) {
        values.push_back(toNeo4jValue(item));
    }
    
    return neo4j_list(values.data(), values.size());
}

neo4j_value_t Neo4jValueConverter::toNeo4jValue(const graph::Neo4jMap& map) {
    std::vector<neo4j_map_entry_t> entries;
    
    for (const auto& field : map.fields()) {
        std::string key = field.first;
        key = field.first;
        const graph::Neo4jValue& value = field.second;
        
        neo4j_value_t neo4j_val = toNeo4jValue(value);
        entries.push_back({ .key = neo4j_string(key.c_str()), .value = neo4j_val });
    }

    return neo4j_map(entries.data(), entries.size());
}

std::string Neo4jValueConverter::toString(neo4j_value_t value) {
    if (neo4j_is_null(value)) {
        return "null";
    }
    
    char buffer[4096];
    neo4j_tostring(value, buffer, sizeof(buffer));
    return std::string(buffer);
}